﻿#include "sys_logger_impl.hh"
#include "../../thirdparty/klogger/klogger/interface/logger.h"

#ifndef WIN32
#include <syslog.h>
#else
#include "os_service_windows.hh"
#endif // WIN32

#include <cstdarg>
#include <cstdio>

kratos::service::SysLoggerImpl::SysLoggerImpl(const std::string &name) {
#ifndef WIN32
  // 开启syslog
  openlog(name.c_str(), LOG_CONS | LOG_PID | LOG_NDELAY, 0);
#endif // WIN32
}

kratos::service::SysLoggerImpl::~SysLoggerImpl() {
#ifndef WIN32
  // 关闭syslog
  closelog();
#endif // WIN32
}

auto kratos::service::SysLoggerImpl::log(int level, const char *fmt, ...)
    -> void {
  // 将容器日志等级转换为操作系统日志等级
#ifndef WIN32
  switch (level) {
  case klogger::Logger::INFORMATION:
  case klogger::Logger::VERBOSE:
    level = LOG_INFO;
    break;
  case klogger::Logger::DIAGNOSE:
    level = LOG_DEBUG;
    break;
  case klogger::Logger::WARNING:
    level = LOG_WARNING;
    break;
  case klogger::Logger::FAILURE:
  case klogger::Logger::EXCEPTION:
    level = LOG_ERR;
    break;
  case klogger::Logger::FATAL:
    level = LOG_CRIT;
    break;
  default:
    level = LOG_INFO;
    break;
  }
#else
  WORD event_flags = 0;
  switch (level) {
  case klogger::Logger::INFORMATION:
  case klogger::Logger::VERBOSE:
  case klogger::Logger::DIAGNOSE:
    event_flags = EVENTLOG_INFORMATION_TYPE;
    break;
  case klogger::Logger::WARNING:
    event_flags = EVENTLOG_WARNING_TYPE;
    break;
  case klogger::Logger::FAILURE:
  case klogger::Logger::EXCEPTION:
  case klogger::Logger::FATAL:
    event_flags = EVENTLOG_ERROR_TYPE;
    break;
  default:
    event_flags = EVENTLOG_INFORMATION_TYPE;
    break;
  }
#endif // WIN32
  constexpr static int BUFFER_LEN = 2000;
  static char buffer[BUFFER_LEN];
  std::va_list va_ptr;
  va_start(va_ptr, fmt);
  std::vsnprintf(buffer, sizeof(buffer) - 1, fmt, va_ptr);
  va_end(va_ptr);
#ifndef WIN32
  // syslog
  syslog(level, "%s", buffer);
#else
  // Windows event report
  syslog(event_flags, buffer);
#endif // WIN32
}
